package com.ccteam.fluidmusic.ui.user

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.setFragmentResultListener
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.FragmentNavigatorExtras
import androidx.navigation.fragment.findNavController
import androidx.paging.LoadState
import androidx.recyclerview.widget.ConcatAdapter
import com.ccteam.fluidmusic.NavAlbumDirections
import com.ccteam.fluidmusic.NavMomentDetailDirections
import com.ccteam.fluidmusic.NavPlaylistSheetDirections
import com.ccteam.fluidmusic.R
import com.ccteam.fluidmusic.databinding.FragmentUserMomentsBinding
import com.ccteam.fluidmusic.fluidmusic.common.utils.MediaIDHelper
import com.ccteam.fluidmusic.utils.EventObserver
import com.ccteam.fluidmusic.ui.moment.AddMomentActivity
import com.ccteam.fluidmusic.view.adapters.moment.MomentsItemCallback
import com.ccteam.fluidmusic.view.adapters.moment.MomentsListPagerAdapter
import com.ccteam.fluidmusic.view.adapters.paging.CustomLoadStateAdapter
import com.ccteam.fluidmusic.view.adapters.toolbar.ToolbarTitleAdapter
import com.ccteam.fluidmusic.view.base.LightBounceEdgeEffectFactory
import com.ccteam.fluidmusic.view.bean.LoadMessage
import com.ccteam.fluidmusic.widget.AnimToolbarScrollListener
import com.ccteam.fluidmusic.view.components.CornerImageWrapperView
import com.ccteam.fluidmusic.widget.SNACKBAR_ALL_BOTTOM_BAR
import com.ccteam.fluidmusic.widget.snackbar
import com.ccteam.fluidmusic.ui.moment.PublishMomentFragment
import com.ccteam.fluidmusic.ui.MainActivityViewModel
import com.ccteam.fluidmusic.ui.moment.MomentsHomeViewModel
import com.ccteam.fluidmusic.ui.moment.REFRESH_MOMENT_KEY
import com.ccteam.fluidmusic.ui.moment.imageview.ImageBrowseActivityDirections
import com.ccteam.fluidmusic.ui.moment.imageview.ImageBrowseData
import com.ccteam.fluidmusic.ui.moment.imageview.ImageViewData
import com.ccteam.fluidmusic.ui.music.MusicInfoViewModel
import com.ccteam.model.moment.MOMENT_SHARE_TYPE_ALBUM
import com.ccteam.model.moment.MOMENT_SHARE_TYPE_MUSIC
import com.ccteam.model.moment.MOMENT_SHARE_TYPE_PLAYLIST
import com.ccteam.shared.result.moment.MomentListItem
import com.ccteam.shared.result.title.ToolbarTitleItem
import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import javax.inject.Inject

/**
 * @author Xiaoc
 * @since 2021/4/7
 *
 * 用户自己的朋友圈Fragment
 */
@AndroidEntryPoint
class UserMomentsFragment: Fragment() {

    private var _binding: FragmentUserMomentsBinding? = null
    private val binding get() = _binding!!

    @Inject lateinit var lightBounceEdgeEffectFactory: LightBounceEdgeEffectFactory

    private val momentsListViewModel by viewModels<UserMomentsViewModel>()
    private val momentsHomeViewModel by viewModels<MomentsHomeViewModel>()
    private val mainActivityViewModel by activityViewModels<MainActivityViewModel>()
    private val musicInfoViewModel by viewModels<MusicInfoViewModel>()

    private lateinit var dataAdapter: MomentsListPagerAdapter

    private val startForResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
        if (result.resultCode == Activity.RESULT_OK) {
            val intent = result.data
            if(intent != null){
                if(intent.getBooleanExtra(PublishMomentFragment.SHOULD_REFRESH_MOMENT,false)){
                    dataAdapter.refresh()
                }
            }
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentUserMomentsBinding.inflate(inflater,container,false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val titleAdapter = ToolbarTitleAdapter()
        titleAdapter.submitList(listOf(ToolbarTitleItem(getString(R.string.description_me_moments))))

        binding.toolbarMomentsHome.setNavigationOnClickListener {
            findNavController().navigateUp()
        }

        lightBounceEdgeEffectFactory.applyBounceView(binding.rvMomentsHome,this)
        binding.rvMomentsHome.edgeEffectFactory = lightBounceEdgeEffectFactory

        binding.rvMomentsHome.addOnScrollListener(AnimToolbarScrollListener(binding.toolbarTitle))
        dataAdapter = MomentsListPagerAdapter(imageCallback,momentsCallback)
        binding.rvMomentsHome.adapter = ConcatAdapter(titleAdapter,dataAdapter.withLoadStateFooter(
            CustomLoadStateAdapter(dataAdapter,true){
                dataAdapter.retry()
            }
        ))

        binding.refreshView.setOnRefreshListener {
            dataAdapter.refresh()
        }

        viewLifecycleOwner.lifecycleScope.launch {
            momentsListViewModel.momentsList.collectLatest {
                dataAdapter.submitData(it)
            }
        }

        /**
         * 监听是否处于登录状态，如果不处于登录状态不显示发布广场按钮
         */
        momentsHomeViewModel.isLogin.observe(viewLifecycleOwner, { isLogin ->
            binding.btnAddMoment.isVisible = isLogin
        })

        musicInfoViewModel.loadMessage.observe(viewLifecycleOwner,EventObserver{
            when(it){
                is LoadMessage.Loading ->{
                    view.snackbar(R.string.description_moment_music_loading, SNACKBAR_ALL_BOTTOM_BAR, Snackbar.LENGTH_LONG)
                        .show()
                }
                is LoadMessage.Error ->{
                    view.snackbar(R.string.description_moment_music_error, SNACKBAR_ALL_BOTTOM_BAR).show()
                }
                is LoadMessage.Success ->{
                    mainActivityViewModel.addQueueItem(musicInfoViewModel.currentMediaId,
                        MediaIDHelper.ONLINE_MEDIA_CACHE, MediaIDHelper.PLAYLIST_ADD_TYPE_NOW_PLAY)
                }
            }
        })

        viewLifecycleOwner.lifecycleScope.launch {
            dataAdapter.loadStateFlow.collectLatest { state ->
                binding.refreshView.isRefreshing = state.refresh is LoadState.Loading
                binding.statusView.changeToLoadingStatus(state.refresh is LoadState.Loading)
                binding.statusView.changeToErrorStatus(state.refresh,
                    state.append.endOfPaginationReached && dataAdapter.itemCount < 1)
            }
        }

        binding.btnAddMoment.setOnClickListener {
            startForResult.launch(Intent(requireContext(), AddMomentActivity::class.java))
        }

        binding.statusView.setRetryClickListener {
            dataAdapter.refresh()
        }
    }

    private val momentsCallback = object: MomentsItemCallback {
        override fun itemClicked(view: View,item: MomentListItem) {
            val transitionName = getString(R.string.moment_detail_transition_name)
            val extra = FragmentNavigatorExtras(view to transitionName)

            findNavController().navigate(
                NavMomentDetailDirections
                .actionGlobalMomentDetailFragment(item.id),extra)
        }

        override fun shareContentClicked(view: View,item: MomentListItem.MomentShareItem) {
            when(item.type){
                MOMENT_SHARE_TYPE_ALBUM ->{
                    val transitionName = getString(R.string.album_detail_transition_name)
                    val extra = FragmentNavigatorExtras(view to transitionName)

                    findNavController().navigate(
                        NavAlbumDirections.actionGlobalAlbumDetailFragment(item.id),extra
                    )
                }
                MOMENT_SHARE_TYPE_PLAYLIST ->{
                    val transitionName = getString(R.string.playlist_detail_transition_name)
                    val extra = FragmentNavigatorExtras(view to transitionName)

                    findNavController().navigate(
                        NavPlaylistSheetDirections.actionGlobalPlaylistSheetDetailFragment(item.id),extra
                    )
                }
                MOMENT_SHARE_TYPE_MUSIC ->{
                    viewLifecycleOwner.lifecycleScope.launch {
                        musicInfoViewModel.prepareMusic(item.id)
                    }
                }
            }
        }

    }

    override fun onResume() {
        super.onResume()

        setFragmentResultListener(REFRESH_MOMENT_KEY){ _, bundle ->
            if(bundle.getBoolean(REFRESH_MOMENT_KEY)){
                dataAdapter.refresh()
            }
        }
    }

    private val imageCallback = object: CornerImageWrapperView.ImageEventListener<MomentListItem.MomentImageItem>{

        override fun imageClick(
            view: View,
            position: Int,
            imageList: List<MomentListItem.MomentImageItem>
        ) {
            findNavController().navigate(
                ImageBrowseActivityDirections.actionGlobalImageBrowseActivity(
                    ImageBrowseData(position,imageList.map {
                        ImageViewData(it.id,it.imageUrl)
                    })
                ))
        }

    }

    override fun onDestroyView() {
        super.onDestroyView()

        binding.rvMomentsHome.clearOnScrollListeners()
        _binding = null
    }
}